//package main
//
//import (
//	"context"
//	"fmt"
//	"hello_server/pb"
//	"io"
//	"net"
//	"strings"
//
//	"google.golang.org/grpc"
//)
//
//// hello server
//
//type server struct {
//	pb.UnimplementedGreeterServer
//}
//
//func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloResponse, error) {
//	return &pb.HelloResponse{Reply: "Hello " + in.Name}, nil
//}
//
//// LotsOfReplies 返回使用多种语言打招呼
//func (s *server) LotsOfReplies(in *pb.HelloRequest, stream pb.Greeter_LotsOfRepliesServer) error {
//	words := []string{
//		"你好",
//		"hello",
//		"こんにちは",
//		"안녕하세요",
//	}
//
//	for _, word := range words {
//		data := &pb.HelloResponse{
//			Reply: word + in.GetName(),
//		}
//		// 使用Send方法返回多个数据
//		if err := stream.Send(data); err != nil {
//			return err
//		}
//	}
//	return nil
//}
//
//// LotsOfGreetings 接收流式数据
//func (s *server) LotsOfGreetings(stream pb.Greeter_LotsOfGreetingsServer) error {
//	reply := "你好："
//	for {
//		// 接收客户端发来的流式数据
//		res, err := stream.Recv()
//		if err == io.EOF {
//			// 最终统一回复
//			return stream.SendAndClose(&pb.HelloResponse{
//				Reply: reply,
//			})
//		}
//		if err != nil {
//			return err
//		}
//		reply += res.GetName()
//	}
//}
//
//// BidiHello 双向流式打招呼
//func (s *server) BidiHello(stream pb.Greeter_BidiHelloServer) error {
//	for {
//		// 接收流式请求
//		in, err := stream.Recv()
//		if err == io.EOF {
//			//表示到达了流的末尾
//			return nil
//		}
//		if err != nil {
//			return err
//		}
//
//		reply := magic(in.GetName()) // 对收到的数据做些处理
//
//		// 返回流式响应
//		if err := stream.Send(&pb.HelloResponse{Reply: reply}); err != nil {
//			return err
//		}
//	}
//}
//
//// magic 一段价值连城的“人工智能”代码
//func magic(s string) string {
//	s = strings.ReplaceAll(s, "吗", "")
//	s = strings.ReplaceAll(s, "吧", "")
//	s = strings.ReplaceAll(s, "你", "我")
//	s = strings.ReplaceAll(s, "？", "!")
//	s = strings.ReplaceAll(s, "?", "!")
//	return s
//}
//
//func main() {
//	// 监听本地的8972端口
//	lis, err := net.Listen("tcp", ":8972")
//	if err != nil {
//		fmt.Printf("failed to listen: %v", err)
//		return
//	}
//	s := grpc.NewServer()                  // 创建gRPC服务器
//	pb.RegisterGreeterServer(s, &server{}) // 在gRPC服务端注册服务
//	// 启动服务
//	err = s.Serve(lis)
//	if err != nil {
//		fmt.Printf("failed to serve: %v", err)
//		return
//	}
//}

package main

import (
	"context"
	"fmt"
	"google.golang.org/grpc/credentials"
	"hello_server/pb"
	"log"
	"net"
	"sync"

	"google.golang.org/grpc"
)

// grpc server

type server struct {
	pb.UnimplementedGreeterServer
	mu    sync.Mutex     // count的并发锁
	count map[string]int // 记录每个name的请求次数
}

// SayHello 是我们需要实现的方法
// 这个方法是我们对外提供的服务
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloResponse, error) {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.count[in.Name]++ // 记录用户的请求次数
	// 超过1次就返回错误
	//if s.count[in.Name] > 1 {
	//	st := status.New(codes.ResourceExhausted, "Request limit exceeded.")
	//	ds, err := st.WithDetails(
	//		&errdetails.QuotaFailure{
	//			Violations: []*errdetails.QuotaFailure_Violation{{
	//				Subject:     fmt.Sprintf("name:%s", in.Name),
	//				Description: "限制每个name调用一次",
	//			}},
	//		},
	//	)
	//	if err != nil {
	//		return nil, st.Err()
	//	}
	//	return nil, ds.Err()
	//}
	// 正常返回响应
	reply := "hello " + in.GetName()
	return &pb.HelloResponse{Reply: reply}, nil
}

func main() {
	// 加载证书
	ca, err := credentials.NewServerTLSFromFile("ca/server.crt", "ca/server.key")
	if err != nil {
		log.Fatalf("Failed to load certificates: %v", err)
	}

	// 创建 gRPC 服务器
	s := grpc.NewServer(grpc.Creds(ca))

	// 注册服务，注意初始化count
	pb.RegisterGreeterServer(s, &server{count: make(map[string]int)})

	// 启动服务
	l, err := net.Listen("tcp", ":8972")
	if err != nil {
		fmt.Printf("failed to listen, err:%v\n", err)
		return
	}
	err = s.Serve(l)
	if err != nil {
		fmt.Printf("failed to serve,err:%v\n", err)
		return
	}
}
